/*************************************************************************
> File Name: 1.c
> Author: hzy
> Created Time: 2023-09-26 15:48:27
> Description:
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pcap/pcap.h>
#include <arpa/inet.h>
#include <unistd.h>

int main(int argc, char const *argv[])
{
    // 获取可用的网卡
    char *device = pcap_lookupdev(NULL);
    if (device == NULL)
    {
        perror("pcap_lookupdev");
        exit(-1);
    }

    // 打开可用的网卡
    pcap_t *libcap = pcap_open_live(device, 1500, 1, 20000, NULL);
    if (libcap == NULL)
    {
        perror("pcap_open_live");
        exit(-1);
    }

    while (1)
    {
        // sleep(1);
        // 捕获一个数据包
        struct pcap_pkthdr data_info;
        unsigned char *data = pcap_next(libcap, &data_info);

        unsigned char dest_mac[18] = {0};
        unsigned char src_mac[18] = {0};
        sprintf(dest_mac, "%02x:%02x:%02x:%02x:%02x:%02x", data[0], data[1], data[2], data[3], data[4], data[5]);
        sprintf(src_mac, "%02x:%02x:%02x:%02x:%02x:%02x", data[6], data[7], data[8], data[9], data[10], data[11]);
        printf("dest_mac:%s | src_mac:%s\n", dest_mac, src_mac);

        unsigned short type = ntohs(*(unsigned short *)(data + 12));
        if (type == 0x0800)
        {
            printf("--------------------IP--------------------\n");
            unsigned char *ip_buf = data + 14;

            unsigned char ip_type = ip_buf[9]; // 得到上一层数据协议的类型

            unsigned char ip_head_len = (ip_buf[0] & 0x0f) * 4;

            unsigned char src_ip[16] = {};
            unsigned char dest_ip[16] = {};

            inet_ntop(AF_INET, ip_buf + 12, src_ip, sizeof(src_ip));
            inet_ntop(AF_INET, ip_buf + 16, dest_ip, sizeof(dest_ip));

            if (ip_type == 6 || ip_type == 17)
            {
                printf("--------------------TCP|UDP--------------------\n");
                unsigned char *t_buf = ip_buf + ip_head_len;
                unsigned short src_port = ntohs(*(unsigned short *)(t_buf + 0));
                unsigned short dest_port = ntohs(*(unsigned short *)(t_buf + 2));
                printf("src_ip:%s | dest_ip:%s\n", src_ip, dest_ip);
                printf("src_port:%d | dest_port:%d\n\n", src_port, dest_port);
            }
        }
    }

    return 0;
}